cmake_minimum_required(VERSION 3.22)
enable_language(C ASM)

project(ffi) 

set(COPY_COMMANDS "")

if ("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "arm")  
    set(INCLUDE_DIRS  
        "${CMAKE_CURRENT_SOURCE_DIR}"  
        "${CMAKE_CURRENT_SOURCE_DIR}/include"  
        "${CMAKE_CURRENT_SOURCE_DIR}/src/arm"  
    )  
    set(CFLAGS_ARM  
        "-DTARGET=ARM"  
        "-Wno-sign-compare"  
        "-Wno-implicit-function-declaration"  
        "-Wno-extern-initializer"  
    )  
    set(SOURCES_ARM  
        "src/arm/ffi.c"  
        "src/arm/sysv.S"  
        "src/closures.c"  
        "src/java_raw_api.c"  
        "src/prep_cif.c"  
        "src/raw_api.c"
        "src/types.c"
    )

    list(APPEND COPY_COMMANDS  
        COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/src/arm/ffitarget.h ${CMAKE_INSTALL_PREFIX}/include/libffi/
        COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/src/arm/internal.h ${CMAKE_INSTALL_PREFIX}/include/libffi/ 
    )
elseif ("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64")  
    set(INCLUDE_DIRS  
        "${CMAKE_CURRENT_SOURCE_DIR}"  
        "${CMAKE_CURRENT_SOURCE_DIR}/include"  
        "${CMAKE_CURRENT_SOURCE_DIR}/src/x86"  
    )  
    set(CFLAGS_X86_64  
        "-DTARGET=X86_64"  
        "-Wno-sign-compare"  
        "-Wno-implicit-function-declaration"  
        "-Wno-extern-initializer"  
    )  
    set(SOURCES_X86_64  
        "src/closures.c"  
        "src/java_raw_api.c"  
        "src/prep_cif.c"  
        "src/raw_api.c"  
        "src/types.c"  
        "src/x86/ffi64.c"  
        "src/x86/unix64.S"  
    )  
    list(APPEND COPY_COMMANDS  
        COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/src/x86/asmnames.h ${CMAKE_INSTALL_PREFIX}/include/libffi/  
        COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/src/x86/ffitarget.h ${CMAKE_INSTALL_PREFIX}/include/libffi/  
        COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/src/x86/internal.h ${CMAKE_INSTALL_PREFIX}/include/libffi/  
        COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/src/x86/internal64.h ${CMAKE_INSTALL_PREFIX}/include/libffi/  
    )
elseif ("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "aarch64")  
    set(INCLUDE_DIRS  
        "${CMAKE_CURRENT_SOURCE_DIR}"  
        "${CMAKE_CURRENT_SOURCE_DIR}/include"  
        "${CMAKE_CURRENT_SOURCE_DIR}/src/aarch64"  
    )  
    set(CFLAGS_AARCH64  
        "-DTARGET=AARCH64"  
        "-Wno-sign-compare"  
        "-Wno-implicit-function-declaration"  
        "-Wno-extern-initializer" 
    )  
    set(SOURCES_AARCH64  
        "src/aarch64/ffi.c"  
        "src/aarch64/sysv.S"  
        "src/closures.c"  
        "src/java_raw_api.c"  
        "src/prep_cif.c"  
        "src/raw_api.c"  
        "src/types.c"  
    )
    list(APPEND COPY_COMMANDS  
        COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/src/aarch64/ffitarget.h ${CMAKE_INSTALL_PREFIX}/include/libffi/  
        COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/src/aarch64/internal.h ${CMAKE_INSTALL_PREFIX}/include/libffi/  
    ) 
else()  
    message(FATAL_ERROR "Unsupported target CPU architecture: ${TARGET_CPU}")  
endif()

set(ASM_OPTIONS "-x assembler-with-cpp")
set(CMAKE_ASM_FLAGS "${CFLAGS} ${ASM_OPTIONS}")

add_compile_options(${CFLAGS_ARM} ${CFLAGS_X86_64} ${CFLAGS_AARCH64})

add_library(ffi SHARED ${SOURCES_ARM} ${SOURCES_X86_64} ${SOURCES_AARCH64})

target_include_directories(ffi PRIVATE ${INCLUDE_DIRS}) 

add_custom_command(TARGET ffi POST_BUILD
	COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_INSTALL_PREFIX}/lib
	COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_INSTALL_PREFIX}/include/libffi
	COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:ffi> ${CMAKE_INSTALL_PREFIX}/lib/
	COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/fficonfig.h ${CMAKE_INSTALL_PREFIX}/include/libffi/
	COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/include/ ${CMAKE_INSTALL_PREFIX}/include/libffi/
	COMMAND ${COPY_COMMANDS}
)

#install(TARGETS ffi DESTINATION ${CMAKE_INSTALL_PREFIX}/lib)
#install(FILES ${LibA_HEADERS} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/ffi)
